package com.ruoyi.gd.dbjlb.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
import com.ruoyi.common.utils.JsonUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.gd.cgbjd.domain.ZCgbjd;
import com.ruoyi.gd.cgbjd.mapper.ZCgbjdMapper;
import com.ruoyi.gd.dbjlb.domain.TemplateData;
import com.ruoyi.gd.dbjlb.domain.vo.ImportZDbjlbVo;
import com.ruoyi.gd.fj.domain.bo.ZFujianBo;
import com.ruoyi.gd.fj.domain.vo.ZFujianVo;
import com.ruoyi.gd.fj.service.IZFujianService;
import com.ruoyi.gd.khbjk.domain.ZKhbjk;
import com.ruoyi.gd.khbjk.mapper.ZKhbjkMapper;
import lombok.RequiredArgsConstructor;

import org.apache.poi.openxml4j.util.ZipSecureFile;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.ruoyi.gd.dbjlb.domain.bo.ZDbjlbBo;
import com.ruoyi.gd.dbjlb.domain.vo.ZDbjlbVo;
import com.ruoyi.gd.dbjlb.domain.ZDbjlb;
import com.ruoyi.gd.dbjlb.mapper.ZDbjlbMapper;
import com.ruoyi.gd.dbjlb.service.IZDbjlbService;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;

/**
 * 待报价列Service业务层处理
 *
 * @author ruoyi
 * @date 2024-07-02
 */
@RequiredArgsConstructor
@Service
public class ZDbjlbServiceImpl implements IZDbjlbService {

    private final ZDbjlbMapper baseMapper;

    @Autowired
    private IZFujianService fujianService;

    @Value("${upload.path}")
    private String uploadPath;

    @Autowired
    private ZCgbjdMapper ZCgbjdMapper;

    @Autowired
    private ZKhbjkMapper zKhbjkMapper;

    /**
     * 查询待报价列
     */
    @Override
    public ZDbjlbVo queryById(String id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询待报价列列表
     */
    @Override
    public TableDataInfo<ZDbjlbVo> queryPageList(ZDbjlbBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<ZDbjlb> lqw = buildQueryWrapper(bo);
        Page<ZDbjlbVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询待报价列列表
     */
    @Override
    public List<ZDbjlbVo> queryList(ZDbjlbBo bo) {
        LambdaQueryWrapper<ZDbjlb> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<ZDbjlb> buildQueryWrapper(ZDbjlbBo bo) {
        LambdaQueryWrapper<ZDbjlb> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getKhid()), ZDbjlb::getKhid, bo.getKhid());
        lqw.like(StringUtils.isNotBlank(bo.getKhname()), ZDbjlb::getKhname, bo.getKhname());
        lqw.eq(StringUtils.isNotBlank(bo.getKhdz()), ZDbjlb::getKhdz, bo.getKhdz());
        lqw.eq(StringUtils.isNotBlank(bo.getBjfj()), ZDbjlb::getBjfj, bo.getBjfj());
        lqw.eq(StringUtils.isNotBlank(bo.getScfj()), ZDbjlb::getScfj, bo.getScfj());
        lqw.eq(StringUtils.isNotBlank(bo.getBz()), ZDbjlb::getBz, bo.getBz());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), ZDbjlb::getStatus, bo.getStatus());
        return lqw;
    }

    /**
     * 新增待报价列
     */
    @Override
    public Boolean insertByBo(ZDbjlbBo bo) {
        ZDbjlb add = BeanUtil.toBean(bo, ZDbjlb.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改待报价列
     */
    @Override
    public Boolean updateByBo(ZDbjlbBo bo) {
        ZDbjlb update = BeanUtil.toBean(bo, ZDbjlb.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(ZDbjlb entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除待报价列
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 生成完工单数据
     * @param bo
     * @return
     */
    @Override
    public JSONObject genQuotation(ZDbjlbBo bo) {
        JSONObject object = new JSONObject();
        // 1.解析上传的报价单
        if (StringUtils.isNotEmpty(bo.getBjfj())) {
            List<ZFujianVo> zFujianVos = fujianService.queryListByIdOrdery(bo.getBjfj());
            for (ZFujianVo zFujianVo : zFujianVos) {
                String fjpath = uploadPath + zFujianVo.getFjpath();

                FileInputStream fis = null;
                FileOutputStream fos = null;
                try  {
                    fis = new FileInputStream(fjpath);
                    ZipSecureFile.setMinInflateRatio(0.0);
                    Workbook workbook = new XSSFWorkbook(fis);
                    Sheet sheet = workbook.getSheetAt(0); // 假设我们要操作第一个sheet
                    double hjje = 0;
                    int lastRowNum = sheet.getLastRowNum();
                    for (int row = 0; row <= lastRowNum; row++) { // 一行数据
                        Row cells = sheet.getRow(row);
                        // 在第一行，第三列，添加单位
                        if (row == 2) {
                            cells.getCell(0).setCellValue(TemplateData.wtdw + bo.getKhname());
                        }
                        // 在第六行，第二列，添加地址
                        if (row == 5) {
                            cells.getCell(1).setCellValue(bo.getKhdz());
                        }
                        // 在最后一行，第四列，添加日期
                        int rowNum = cells.getRowNum();  // 获取最后一行
                        if(lastRowNum == rowNum) {
                            cells.getCell(4).setCellValue(TemplateData.bjrq + new SimpleDateFormat("yyyy-MM-dd").format(bo.getBjrq()));
                        }
                        if (row >= 7) {
                            // 1 是仪器名称   2 型号  3.编号  4.单价  5.数量  6.小计  7.服务方式  8.备注
                            Cell yqmc = cells.getCell(1);  // 获取当前行的仪器名称
                            Cell xh = cells.getCell(2);  // 获取当前行的仪器名称
                            String one = yqmc.getStringCellValue();
                            if(null != yqmc && !"下场费".equals(one.trim()) && !"合计金额".equals(one.trim()) && null != xh) {
                                hjje += handleData(cells, bo);
                            }
                            if (null != yqmc && "合计金额".equals(one.trim())) {
                                Cell hj = cells.getCell(6);
                                hj.setCellType(CellType.NUMERIC);
                                hj.setCellValue(hjje);
                            }
                        }
                    }
                    JSONObject file = createFile(bo);
                    fos = new FileOutputStream(file.getStr("filePathAll"));
                    workbook.write(fos);

                    // 处理完毕，则将附件保存到附件表里，返回前端
                    ZFujianBo fujianBo = new ZFujianBo();
                    fujianBo.setFjid(IdUtil.simpleUUID());  //设置附件id
                    fujianBo.setFjname(file.getStr("fileName"));   //设置附件名称
                    fujianBo.setFjpath(file.getStr("filePath"));  //设置附件路径
                    fujianBo.setFjtype(file.getStr("suffix"));
                    fujianService.insertByBo(fujianBo);

                    ZDbjlb zDbjlb = new ZDbjlb();
                    zDbjlb.setId(bo.getId());
                    zDbjlb.setScfj(fujianBo.getFjid());
                    // 设置已生成报价单
                    zDbjlb.setStatus("1");
                    baseMapper.updateById(zDbjlb);

                    object = JSONUtil.parseObj(fujianBo);

                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if (fis != null) {
                        try {
                            fis.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (fos != null) {
                        try {
                            fos.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
        return object;
    }

    private double handleData(Row row,  ZDbjlbBo bo) {
        double hjje = 0;
        /**
         * 1. 常规报价： 通过仪器名字查询查询
         * 2. 完工单报价： 通过导入类型数据进行查询
         * 3. 常规+完工单报价： 先通过导入类型进行查询数据，如果没有的话，则通过仪器名称查询数据
         */
        // 1 是仪器名称   2 型号  3.编号  4.单价  5.数量  6.小计  7.服务方式  8.备注
        if (bo.getBjlx().equals("1")) {
            // 获取仪器名称
            Cell cell = row.getCell(1);
            String yqmc = cell.getStringCellValue();
            // 构建查询条件
            if (StringUtils.isNotEmpty(yqmc)) {
                LambdaQueryWrapper<ZCgbjd> lqw = Wrappers.lambdaQuery();
                lqw.eq(ZCgbjd::getName, yqmc);
                List<ZCgbjd> zCgbjds = ZCgbjdMapper.selectList(lqw);
                if (zCgbjds.size() > 0) {
                    ZCgbjd zCgbjd = zCgbjds.get(0);
                    // 给当前的第4列设置单价
                    Cell dj = row.getCell(4);
                    dj.setCellValue(zCgbjd.getDj());
                    // 设置金额
                    // 判断当前是否有数量，如果有数量则计算单价
                    Cell sl = row.getCell(5);
                    if (sl.getCellType() != CellType.BLANK) {
                        double num = sl.getNumericCellValue();
                        double sum = zCgbjd.getDj() * num;
                        Cell xj = row.getCell(6);
                        xj.setCellValue(sum);
                        hjje += sum;
                    }
                    // 设置服务方式
                    Cell fwfs = row.getCell(7);
                    fwfs.setCellValue("常规报价");
                }
            }

        }else if(bo.getBjlx().equals("2")) {
            hjje += handleWgd(row, bo);
        }else {
            hjje += handleWgd(row, bo);
        }

        return hjje;
    }

    private double handleWgd(Row row, ZDbjlbBo bo) {
        double hjje = 0;
        // 仪器名称 （yqmc）  仪器型号（yqxh）  出厂编号（ccbh）  管理编号（glbh）
        LambdaQueryWrapper<ZKhbjk> lqw = Wrappers.lambdaQuery();
        String drlx = bo.getDrlx();
        // 设置当前的客户
        lqw.eq(ZKhbjk::getKhname, bo.getKhname());
        if ("yqmc".equals(drlx)) {
            // 获取仪器名称
            Cell cell = row.getCell(1);
            String yqmc = cell.getStringCellValue().trim();
            // 设置仪器名称条件
            lqw.eq(ZKhbjk::getName, yqmc);
        }
        if ("yqxh".equals(drlx)) {
            // 获取仪器型号
            Cell cell = row.getCell(2);
            String yqxh = cell.getStringCellValue().trim();
            // 设置仪器型号
            lqw.eq(ZKhbjk::getXhgg, yqxh);
        }
        if ("ccbh".equals(drlx)) {
            // 获取出厂编号
            Cell cell = row.getCell(3);
            String yqxh = cell.getStringCellValue().trim();
            if (StringUtils.isEmpty(yqxh)) {
                yqxh = "/";
            }
            // 设置出厂编号
            lqw.eq(ZKhbjk::getXhgg, yqxh);
        }
        // 根据条件查询查询数据
        List<ZKhbjk> zKhbjks = zKhbjkMapper.selectList(lqw);
        if (zKhbjks.size() > 0) {
            ZKhbjk zKhbjk = zKhbjks.get(0);
            // 给当前的第4列设置单价
            Cell dj = row.getCell(4);
            dj.setCellValue(zKhbjk.getDj());
            // 设置金额
            // 判断当前是否有数量，如果有数量则计算单价
            Cell sl = row.getCell(5);
            if (sl.getCellType() != CellType.BLANK) {
                double num = sl.getNumericCellValue();
                double sum = zKhbjk.getDj() * num;
                Cell xj = row.getCell(6);
                xj.setCellValue(sum);
                hjje += sum;
            }

        }else {
            if (bo.getBjlx().equals("3")) {
                // 获取仪器名称
                Cell cell = row.getCell(1);
                String yqmc = cell.getStringCellValue();
                // 设置仪器名称条件
                LambdaQueryWrapper<ZCgbjd> query = Wrappers.lambdaQuery();
                query.eq(ZCgbjd::getName, yqmc);
                List<ZCgbjd> zCgbjds = ZCgbjdMapper.selectList(query);
                if (zCgbjds.size() > 0) {
                    ZCgbjd zCgbjd = zCgbjds.get(0);
                    // 给当前的第4列设置单价
                    Cell dj = row.getCell(4);
                    dj.setCellValue(zCgbjd.getDj());
                    // 设置金额
                    // 判断当前是否有数量，如果有数量则计算单价
                    Cell sl = row.getCell(5);
                    if (sl.getCellType() != CellType.BLANK);
                }
                if (zCgbjds.size() > 0) {
                    ZCgbjd zCgbjd = zCgbjds.get(0);
                    // 给当前的第4列设置单价
                    Cell dj = row.getCell(4);
                    dj.setCellValue(zCgbjd.getDj());
                    // 判断当前是否有数量，如果有数量则计算单价
                    Cell sl = row.getCell(5);
                    if (sl.getCellType() != CellType.BLANK) {
                        double num = sl.getNumericCellValue();
                        double sum = zCgbjd.getDj() * num;
                        Cell xj = row.getCell(6);
                        xj.setCellValue(sum);
                        hjje += sum;
                    }
                }
            }
        }
        // 设置服务方式
        Cell fwfs = row.getCell(7);
        if (bo.getBjlx().equals("2")) {
            fwfs.setCellValue("完工单报价");
        }else if (bo.getBjlx().equals("3")) {
            fwfs.setCellValue("常规+完工单报价");
        }
        return hjje;
    }

    public JSONObject createFile(ZDbjlbBo bo) throws IOException {
        JSONObject json = new JSONObject();
        // 分别获取年、月、日
        LocalDate currentDate = LocalDate.now();
        int year = currentDate.getYear();
        int monthValue = currentDate.getMonthValue();
        int dayOfMonth = currentDate.getDayOfMonth();
        String path = "/" + year + "/" + monthValue + "/" + dayOfMonth + "/" ;
        // 判断当前文件路径的文件夹是否存在，不存在则创建
        if (!Files.exists(Paths.get(uploadPath + path))) {
            // 路径不存在，尝试创建
            try {
                Files.createDirectories(Paths.get(uploadPath + path));
            } catch (Exception e) {
                System.err.println("创建目录时出错: " + e.getMessage());
            }
        }

        SimpleDateFormat format = new SimpleDateFormat("yyyMMdd");
        String date = format.format(new Date());

        String fileId = IdUtil.simpleUUID();
        // 创建文件
        String fileName = uploadPath + path + fileId + ".xlsx";
//        String fileName = uploadPath + path + date + "+报价单+" + bo.getKhname() + ".xlsx";
        json.set("filePathAll", fileName);
        json.set("filePath", path + fileId + ".xlsx");
        json.set("fileName", date + "+报价单+" + bo.getKhname() + ".xlsx");
        json.set("suffix", ".xlsx");
        return json;
    }


}
